package com.yonyou.pmclouds.im.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.pmclouds.basecom.conf.IMProperties;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.im.entity.*;
import com.yonyou.pmclouds.im.service.IMPushLogService;
import com.yonyou.pmclouds.im.service.IMService;
import com.yonyou.pmclouds.im.util.IMHttpTookit;
import com.yonyou.pmclouds.im.util.IMTokenInfo;
import com.yonyou.pmclouds.task.entity.TaskVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class IMServiceImpl implements IMService {


    @Autowired
    private IMProperties imProperties;
    @Autowired
    private IMPushLogService imPushLogService;

    private ObjectMapper mapper = new ObjectMapper();

    private String basicMessage = "您有一条【${srcBillType}】等待办理，点此查看详情。";

    @Override
    public String pushTodoMessage(TaskVO todoTask,boolean timeout) throws BusinessException {

        IMTokenParamVO tokenParam =  getTokenParam();
        IMTokenInfo imTokenInfo = IMTokenInfo.getImTokenInfo(tokenParam,timeout);

        return doPushMessage(todoTask,imTokenInfo);

    }
    /**
    * @Description: 推送消息
    * @param: [todoTask, imTokenInfo]
    * @return: java.lang.String
    * @author: zhangwce
    * @Date: 2018/4/17
    */
    private String doPushMessage(TaskVO todoTask,IMTokenInfo imTokenInfo) throws BusinessException {
        String sendUrl = IMConst.PUSH_MESSAGE_URL;
        sendUrl = sendUrl+imTokenInfo.getToken();

        Map<String, String> headers = new HashMap<String,String>();
        headers.put("Content-Type","application/json");

        String json = buildPushParam(todoTask);

        String result = IMHttpTookit.doPostWithJson(sendUrl,json,headers);

        ObjectMapper mapper = new ObjectMapper();
        Map<String,Object> resultMap = new HashMap<String,Object>();
        try {
            resultMap = mapper.readValue(result,Map.class);
        } catch (Exception e) {
            log.error("推送消息结果解析错误，具体信息为："+result);
        }

        int responseCode =  resultMap.get(IMExceptionResultVO.RESPONSECODE) == null?200: (int)resultMap.get(IMExceptionResultVO.RESPONSECODE);

        if(responseCode != 200){

            handleExceptionInfo(todoTask, responseCode);

            if(IMExceptionCode.TokenInvalid == responseCode){
                // token超时，重新获取token信息并推送问题
                result = pushTodoMessage(todoTask,true);
            }

        }

        return result;
    }

    /**
     * 对推送IM异常的信息进行记录
     *
     * @param todoTask
     * @param responseCode
     * @throws BusinessException
     */
    private void handleExceptionInfo(TaskVO todoTask, int responseCode) throws BusinessException {
        IMPushLogVO logVO = new IMPushLogVO();
        logVO.setBilltype(todoTask.getSrc_bill_type());
        logVO.setPkBill(todoTask.getPk_bill());
        logVO.setExcode(responseCode);
        logVO.setPkSender(todoTask.getPk_sender());
        logVO.setPkReceiver(todoTask.getPk_receiver());
        // IM推送异常信息，状态都标记为未处理，等以后有处理或补发机制再做处理
        logVO.setStatus(IMPushLogConst.UNSOLVED);

        imPushLogService.addIMPushLog(logVO);
    }

    /**
     * 构建消息推送参数
     *
     * @return
     * @throws BusinessException
     */
    private String buildPushParam(TaskVO taskVO) throws BusinessException {
        IMPushParamVO pushParamVO = new IMPushParamVO();
        pushParamVO.setFrom(imProperties.getAccount()+"."+imProperties.getEtpId()+"."+imProperties.getAppId());

        pushParamVO.setTo(new String[]{taskVO.getPk_receiver()});
        Map<String,String> contentMap = new HashMap<String,String>();
        contentMap.put("content",getMesContent(taskVO.getSrc_bill_type()));
        pushParamVO.setContent(contentMap);

        TodoIMExtendVO extendVO = new TodoIMExtendVO();
        extendVO.setBillType(taskVO.getSrc_bill_type());
        extendVO.setBillId(taskVO.getPk_bill());
        extendVO.setTaskId(taskVO.getPk_task());
        pushParamVO.setExtend(extendVO);

        String json = null;
        try {
            json = mapper.writeValueAsString(pushParamVO);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("参数转换JSON出错，具体信息为："+e.getMessage());
            throw new BusinessException("获取IM服务token出错");
        }
        return json;
    }

    /**
    * @Description: 获取具体消息内容
    * @param: [bill_type]
    * @return: java.lang.String
    * @author: zhangwce
    * @Date: 2018/4/17
    */
    private String getMesContent(String bill_type){
        // 您有一条【工作联系】未处理
        String messageDetail = "";
        switch (bill_type){
            case BillTypeConst.WORKCONNECT_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","工作联系");
                break;
            case BillTypeConst.PROBLEMLOG_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","问题记录");
                break;
            case BillTypeConst.PROCEDUREINSPECT_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","工序报验");
                break;
            case BillTypeConst.PROCESSPHOTO_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","工序拍照");
                break;
            case BillTypeConst.ALTER_AND_VISA_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","签证申请");
                break;
            case BillTypeConst.ALTER_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","变更申请");
                break;
            case BillTypeConst.CONSTRUCTIONLOG_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","施工记录");
                break;
            case BillTypeConst.CONSTRUCTION_DIARY_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","施工日志");
                break;
            case BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","综合验收");
                break;
            case BillTypeConst.PROCESS_PLAN_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","进度计划");
                break;
            case BillTypeConst.PROCESS_WRITE_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","进度填报");
                break;
            case BillTypeConst.WORKSTART_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","开工报告");
                break;
            case BillTypeConst.STAGECHECK_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","阶段验收");
                break;
            case BillTypeConst.REPEATWORK_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","复工单");
                break;
            case BillTypeConst.WORKSTOP_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","停工单");
                break;
            case BillTypeConst.PATROL_BILLTYPE:
                messageDetail = basicMessage.replace("${srcBillType}","巡查记录");
                break;
        }

        return  messageDetail;

    }
    /**
    * @Description: 构造token获取参数
    * @param: []
    * @return: com.yonyou.pmclouds.im.entity.IMTokenParamVO
    * @author: zhangwce
    * @Date: 2018/4/17
    */
    private IMTokenParamVO getTokenParam(){

        IMTokenParamVO param = new IMTokenParamVO();
        param.setEtpId(imProperties.getEtpId());
        param.setAppId(imProperties.getAppId());
        param.setClientId(imProperties.getClientId());
        param.setClientSecret(imProperties.getClientSecret());

        return param;
    }
}
